/*
 * io_func.h
 *
 * Created: 30.7.2013 21:32:16
 *  Author: Ferda
 */ 
#pragma once
//============================================================================================

#include <inttypes.h>
#include <avr/io.h>

#include "Configuration.h"
#include "pins_config.h"
#include "digital_pins.h"
#include "system_config.h"
#include "util.h"

#ifdef __cplusplus
	extern "C" {
#endif
	
//==============================================================================================
//
// IO CONFIG
//
//==============================================================================================

#if IO_CONFIG == PRINTER_MAXI_MASTER  
	#define sleep_x()
	#define sleep_y()
	#define sleep_z()
	#define sleep_e()
	
	#define wakeup_x()
	#define wakeup_y()
	#define wakeup_z()
	#define wakeup_e()
#elif IO_CONFIG == PRINTER_MAXI_SLAVE
	// 
#else
	// pud drivers to energy save mode
	#define sleep_x() WritePin(X_HALF_PIN, 1)
	#define sleep_y() WritePin(Y_HALF_PIN, 1)
	#define sleep_z() WritePin(Z_HALF_PIN, 1)
	#define sleep_e() WritePin(E_HALF_PIN, 1) 

	// wakeup drivers from energy save mode
	#define wakeup_x() WritePin(X_HALF_PIN, 0)
	#define wakeup_y() WritePin(Y_HALF_PIN, 0)
	#define wakeup_z() WritePin(Z_HALF_PIN, 0)
	#define wakeup_e() WritePin(E_HALF_PIN, 0)	
#endif

#if IO_CONFIG != PRINTER_MAXI_SLAVE
	#define x_step_high() WritePin(X_STEP_PIN, 1)
	#define x_step_low() WritePin(X_STEP_PIN, 0)

	#define y_step_high() WritePin(Y_STEP_PIN, 1)
	#define y_step_low()  WritePin(Y_STEP_PIN, 0)

	#define z_step_high() WritePin(Z_STEP_PIN, 1)
	#define z_step_low()  WritePin(Z_STEP_PIN, 0)

	#define e1_step_high() WritePin(E1_STEP_PIN, 1)
	#define e1_step_low()  WritePin(E1_STEP_PIN, 0)

	#define e2_step_high() WritePin(E2_STEP_PIN, 1);
	#define e2_step_low()  WritePin(E2_STEP_PIN, 0)

	#define e_step_low() e1_step_low(); e2_step_low()
	//-------------------------------------------------									
	#define set_x_dir(dir) WritePin(X_DIR_PIN, dir)
	#define set_y_dir(dir) WritePin(Y_DIR_PIN, dir)
	#define set_z_dir(dir) WritePin(Z_DIR_PIN, dir)
	#define set_e1_dir(dir) WritePin(E1_DIR_PIN, dir)
	#define set_e2_dir(dir) WritePin(E2_DIR_PIN, dir)
#endif	

//--------------------------------------------------
// fan pwm control
#define set_fan1_pwm(pwm) OCR1AL = pwm
#define set_fan2_pwm(pwm) OCR1BL = pwm
//---------------------------------------------------
// heaters pwm control
#define set_heater1_pwm(pwm) OCR3AL = pwm
#define set_heater2_pwm(pwm) OCR3BL = pwm
#define set_bed_heater_pwm(pwm) OCR3CL = pwm
//------------------------------------------------------------------------
#ifdef EXT2_HEATER_ACTIVE
	// control
	#define turn_control_led_on() asm volatile ( "sbi 0x05, 0 \n\t" ::)
	#define turn_control_led_off() asm volatile ( "cbi 0x05, 0 \n\t" ::)
#else
	#define turn_control_led_on() set_heater2_pwm(255)
	#define turn_control_led_off() set_heater2_pwm(0)
#endif

FORCE_INLINE uint8_t control_pb_status() { return (PINE & 0x80); }


//====================================================================================
// adc start conversion
FORCE_INLINE void adc_start_conversion(uint8_t channel)
{
	ADMUX = channel & 0x07;
	ADCSRA |= (1 << ADSC);
}
//=====================================================================================
// adc wait to adc conversion finish and return value
FORCE_INLINE uint16_t adc_get_result() 
{
	while (ADCSRA & (1 << ADSC))
	;
	
	return ADC;
}
//=====================================================================================
#if IO_CONFIG != PRINTER_MAXI_SLAVE

	FORCE_INLINE void enable_all_drivers()
	{
		WritePin(X_ENABLE_PIN, X_ENABLE_ON);
		WritePin(Y_ENABLE_PIN, Y_ENABLE_ON);
		WritePin(Z_ENABLE_PIN, Z_ENABLE_ON);
		WritePin(E1_ENABLE_PIN, E1_ENABLE_ON);
		WritePin(E2_ENABLE_PIN, E2_ENABLE_ON);
		
		TIMSK4 |= (1 << OCIE4A);
	}
	//=====================================================================================
	FORCE_INLINE void disable_all_drivers()
	{
		WritePin(X_ENABLE_PIN, !X_ENABLE_ON);
		WritePin(Y_ENABLE_PIN, !Y_ENABLE_ON);
		WritePin(Z_ENABLE_PIN, !Z_ENABLE_ON);
		WritePin(E1_ENABLE_PIN, !E1_ENABLE_ON);
		WritePin(E2_ENABLE_PIN, !E2_ENABLE_ON);
		TIMSK4 &= ~(1 << OCIE4A);
	}
#endif
//=================================================================================================================================

void io_init();
void io_uninit();

//==================================================================================================================================

#ifdef __cplusplus
	};
#endif